/*******************************************************************************
 * The MOSES project, model based software engineering of networked embedded systems.
 * 
 * Copyright (C) 2010-2013, University of Applied Sciences Wildau,
 * Telematics Research Group, http://www.tm.th-wildau.de/research-group
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses>.
 * 
 * Contributors:
 *     University of Applied Sciences Wildau - initial API and implementation
 * 
 * If you are interested in a commercial license please contact us via 
 * e-mail: ralf.vandenhouten@th-wildau.de.
 ******************************************************************************/
package de.thwildau.tm.moses.examples.nmea.app;

import java.util.ArrayList;
import java.util.List;

import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

import de.thwildau.tm.moses.examples.nmea.data.Nmea;

/**
 * The table model of {@link Nmea} data objects. Beside the {@link TableModel} for a {@link JTable} this class
 * also acts as a business class which stores the {@link Nmea} objects of the application.
 * 
 * @author Thomas Kistel
 * @version $Revision: 764 $
 */
public class NmeaTableModel extends AbstractTableModel {

    private static final long serialVersionUID = 1L;

    private List<NmeaEntry> nmeas = new ArrayList<>();


    public void addGPS(Nmea nmea) {
        int row = nmeas.size();
        NmeaEntry entry = new NmeaEntry(nmea);
        if (!nmeas.contains(entry)) {
            nmeas.add(entry);
            fireTableRowsInserted(row, row);
        }
    }

    public List<Nmea> getNMEAS() {
        List<Nmea> list = new ArrayList<>();
        for (NmeaEntry entry : nmeas)
            list.add(entry.getNmea());
        return list;
    }

    public int getColumnCount() {
        return 1;
    }

    // gibt die Anzahl Zeilen der Tabelle an
    public int getRowCount() {
        return nmeas.size();
    }

    // gibt den Titel einer Spalte an
    public String getColumnName(int columnIndex) {
        switch (columnIndex) {
            case 0:
                return "Data";
            default:
                throw new IllegalArgumentException("Wrong column " + columnIndex);
        }
    }

    // gibt den Wert einer Zelle an
    public Object getValueAt(int rowIndex, int columnIndex) {
        Nmea nmea = nmeas.get(rowIndex).getNmea();
        switch (columnIndex) {
            case 0:
                return nmea.toString();
            default:
                throw new IllegalArgumentException("Wrong column");
        }
    }

    /**
     * The {@link Nmea} object are stored in a {@link NmeaEntry} class. This class is a decorator
     * which provides {@link #hashCode()} and {@link #equals(Object)} methods for {@link Nmea} objects
     * based on the checksum of the Nmea message.
     * 
     * @see Nmea#getChecksum()
     */
    private static class NmeaEntry {

        private Nmea nmea;


        public NmeaEntry(Nmea nmea) {
            this.nmea = nmea;
        }

        public Nmea getNmea() {
            return nmea;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((nmea == null) ? 0 : nmea.getChecksum());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            NmeaEntry other = (NmeaEntry)obj;
            if (nmea == null) {
                if (other.nmea != null)
                    return false;
            } else if (nmea.getChecksum() != other.nmea.getChecksum())
                return false;
            return true;
        }

    }
}
